package com.meilai.project.service.business.workbench.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.meilai.project.dto.business.workbench.FillWeekCustomerTargetDTO;
import com.meilai.project.dto.business.workbench.SigningTimeDTO;
import com.meilai.project.dto.business.workbench.VisitRecordDTO;
import com.meilai.project.entity.business.contract.ContractApply;
import com.meilai.project.entity.business.customer.*;
import com.meilai.project.entity.business.workbench.*;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.business.contract.ContractApplyMapper;
import com.meilai.project.service.business.customer.*;
import com.meilai.project.service.business.workbench.*;
import com.meilai.project.util.ThreadLocalUserUtil;
import com.meilai.project.vo.business.workbench.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SaleMonthServiceImpl implements SaleMonthService {

    private final static BigDecimal hundred = new BigDecimal(100);

    private final static BigDecimal ten_thousand = new BigDecimal(10000);
    @Autowired
    private YearService yearService;
    @Autowired
    private YearWeekService yearWeekService;
    @Autowired
    private SaleWeekTargetService saleWeekTargetService;
    @Autowired
    private CustomerInfoService customerInfoService;
    @Autowired
    private SaleWeekCustomerTargetService saleWeekCustomerTargetService;
    @Autowired
    private CustomerFollowService customerFollowService;
    @Autowired
    private CustomerFollowAdvanceService customerFollowAdvanceService;
    @Autowired
    private CustomerRecommendedResourcesService customerRecommendedResourcesService;
    @Autowired
    private CustomerEstimateRecordService customerEstimateRecordService;
    @Autowired
    private ContractApplyMapper contractApplyMapper;
    @Autowired
    private CustomerFollowPhotoService customerFollowPhotoService;

    @Autowired
    private CustomerVisitCommentsService customerVisitCommentsService;

    @Override
    public MonthTargetCountVO queryThisMonthTargetData(Integer type) {
        MonthTargetCountVO vo = new MonthTargetCountVO();
        // 获取当前时间
        LocalDate now = LocalDate.now();
        Year year = yearService.getOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, now.getYear()).eq(Year::getType, now.getMonthValue() <= 6 ? 1 : 2));
        vo.setMonth(now.getMonthValue());
        if (year == null) {
            return vo;
        }
        // 获取本月开始时间
        LocalDate month_begin = now.with(TemporalAdjusters.firstDayOfMonth());
        // 获取本月结束时间
        LocalDate month_end = now.with(TemporalAdjusters.lastDayOfMonth());
        // 获取当前人的id
        Long user_id = ThreadLocalUserUtil.get().getId();
        List<YearWeek> list = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, year.getId()).eq(YearWeek::getMonth, now.getMonthValue()));
        // 查询目标数据
        List<Long> week_ids = list.stream().map(YearWeek::getId).collect(Collectors.toList());
        Map<Long, List<YearWeek>> weekMap = list.stream().collect(Collectors.groupingBy(YearWeek::getId));
        if (CollectionUtils.isNotEmpty(week_ids)) {
            List<WeekReplayDetailVO> weekReplayDetailList = new ArrayList<>();
            // 用户每周目标
            List<SaleWeekTarget> weekTargetList = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().eq(SaleWeekTarget::getUser_id, user_id).in(SaleWeekTarget::getWeek_id, week_ids).eq(SaleWeekTarget::getType, type));
            // 查询用户每周拜访的数据
            List<WeekTransactedCustomerDetailVO> weekTransactedCustomerDetailVOS = saleWeekCustomerTargetService.queryUserWeekTargetCustomerByWeekIds(list.stream().map(YearWeek::getId).collect(Collectors.toList()), user_id, type, month_begin, month_end);
            Map<Long, List<WeekTransactedCustomerDetailVO>> weekTransactedCustomerDetailMap = weekTransactedCustomerDetailVOS.stream().collect(Collectors.groupingBy(WeekTransactedCustomerDetailVO::getWeek_id));
            // 查询用户每周需拜访的客户信息
            List<BaseWeekCustomerVO> baseWeekCustomerVOS = customerInfoService.queryCustomerInfoByDate(user_id, type, month_begin, month_end);
            // todo 加入历史拜访客户数据
            Map<Long, CustomerInfo> customer_map = customerInfoService.companyListAll(type).stream().collect(Collectors.toMap(CustomerInfo::getId, Function.identity()));
            List<CustomerFollow> follows = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(customer_map.keySet())) {
                follows = customerFollowService.list(Wrappers.<CustomerFollow>lambdaQuery().in(CustomerFollow::getCustomer_id, customer_map.keySet()).le(CustomerFollow::getFollow_time, month_end).ge(CustomerFollow::getFollow_time, month_begin));
            }
            BigDecimal zero = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
            BigDecimal count = new BigDecimal(0);
            BigDecimal monthCount = new BigDecimal(0);
            if (CollectionUtils.isEmpty(weekTargetList)) {
                for (YearWeek week : list) {
                    WeekReplayDetailVO weekReplayDetailVO = new WeekReplayDetailVO();
                    weekReplayDetailVO.setWeek_id(week.getId());
                    weekReplayDetailVO.setMonth(week.getMonth());
                    weekReplayDetailVO.setBegin_date(week.getBegin_date());
                    weekReplayDetailVO.setEnd_date(week.getEnd_date());
                    weekReplayDetailVO.setCompletion_rate(zero);
                    // 查询时间段内需要拜访的客户信息
                    List<BaseWeekCustomerVO> weekCustomerVOList = baseWeekCustomerVOS.stream().filter(customer -> customer.getNext_visit_time() != null).filter(customer -> (customer.getNext_visit_time().isBefore(weekReplayDetailVO.getEnd_date()) || customer.getNext_visit_time().equals(weekReplayDetailVO.getEnd_date())) && (customer.getNext_visit_time().isAfter(weekReplayDetailVO.getBegin_date()) || customer.getNext_visit_time().equals(weekReplayDetailVO.getBegin_date()))).collect(Collectors.toList());
                    // todo 加入历史拜访数据
                    List<CustomerFollow> collect = follows.stream().filter(item -> (item.getFollow_time().isAfter(week.getBegin_date()) || item.getFollow_time().equals(week.getBegin_date())) && item.getFollow_time().isBefore(week.getEnd_date()) || item.getFollow_time().equals(week.getEnd_date())).collect(Collectors.toList());
                    List<BaseWeekCustomerVO> need_join = new ArrayList<>();
                    // 找出此周期内需要拜访的客户的ids
                    List<Long> customer_ids = weekCustomerVOList.stream().map(BaseWeekCustomerVO::getId).collect(Collectors.toList());
                    // 过滤出此周期内有拜访记录但是再下次拜访客户中搜不到的拜访记录数据
                    List<CustomerFollow> no_has_next_visit_date_list = collect.stream().filter(follow -> !customer_ids.contains(follow.getCustomer_id())).collect(Collectors.toList());
                    no_has_next_visit_date_list.forEach(record -> {
                        if (customer_map.containsKey(record.getCustomer_id())) {
                            BaseWeekCustomerVO t = new BaseWeekCustomerVO();
                            t.setId(record.getCustomer_id());
                            t.setName(customer_map.get(record.getCustomer_id()).getName());
                            t.setNext_visit_time(record.getFollow_time());
                            t.setVisited(true);
                            need_join.add(t);
                        }
                    });
                    // 过滤出此周期内有拜访记录并且也有下次拜访客户的拜访记录数据
                    List<CustomerFollow> has_next_visit_date_list = collect.stream().filter(follow -> customer_ids.contains(follow.getCustomer_id())).collect(Collectors.toList());
                    // 遍历此时间段内需要拜访的客户
                    // 找出是否有和下次拜访时间同一天并且是同一个客户的拜访记录 有则修改拜访状态
                    weekCustomerVOList.forEach(item -> {
                        List<CustomerFollow> followList = has_next_visit_date_list.stream().filter(record -> record.getCustomer_id().equals(item.getId())).collect(Collectors.toList());
                        // 此周期内此客户有拜访并且和下次拜访时间重叠的
                        List<CustomerFollow> collect1 = followList.stream().filter(record -> record.getFollow_time().equals(item.getNext_visit_time())).collect(Collectors.toList());
                        // 此周期内此客户有拜访但是没有下次拜访时间重叠的
                        List<CustomerFollow> collect2 = followList.stream().filter(record -> !record.getFollow_time().equals(item.getNext_visit_time())).collect(Collectors.toList());
                        if (collect1.size() > 0) {
                            item.setVisited(true);
                        } else {
                            item.setVisited(false);
                        }
                        collect2.forEach(record -> {
                            if (customer_map.containsKey(record.getCustomer_id())) {
                                BaseWeekCustomerVO t = new BaseWeekCustomerVO();
                                t.setId(record.getCustomer_id());
                                t.setName(customer_map.get(record.getCustomer_id()).getName());
                                t.setNext_visit_time(record.getFollow_time());
                                t.setVisited(true);
                                need_join.add(t);
                            }
                        });
                    });
                    // 加入拜访记录数据 再进行排序
                    weekCustomerVOList.addAll(need_join);
                    weekCustomerVOList = weekCustomerVOList.stream().sorted(Comparator.comparing(BaseWeekCustomerVO::getNext_visit_time).thenComparing(BaseWeekCustomerVO::getId)).collect(Collectors.toList());
                    weekReplayDetailVO.setNeed_visit_customer_list(weekCustomerVOList);
                    weekReplayDetailVO.setTarget_customer_list(new ArrayList<>());
                    weekReplayDetailList.add(weekReplayDetailVO);
                }
            } else {
                // 获取最新的有效合同数据
                for (SaleWeekTarget target : weekTargetList) {
                    count = count.add(target.getTarget_quota());
                    WeekReplayDetailVO weekReplayDetailVO = new WeekReplayDetailVO();
                    weekReplayDetailVO.setWeek_id(target.getWeek_id());
                    weekReplayDetailVO.setTarget(target.getTarget_quota());
                    if (weekMap.containsKey(target.getWeek_id())) {
                        weekReplayDetailVO.setMonth(weekMap.get(target.getWeek_id()).get(0).getMonth());
                        weekReplayDetailVO.setBegin_date(weekMap.get(target.getWeek_id()).get(0).getBegin_date());
                        weekReplayDetailVO.setEnd_date(weekMap.get(target.getWeek_id()).get(0).getEnd_date());
                    }
                    // 设置本周客户组成
                    List<WeekTransactedCustomerDetailVO> orDefault = weekTransactedCustomerDetailMap.getOrDefault(target.getWeek_id(), new ArrayList<>());
                    weekReplayDetailVO.setTarget_customer_list(orDefault);
                    // 统计本周完成金额
                    BigDecimal weekCount = new BigDecimal(0);
                    for (WeekTransactedCustomerDetailVO weekTransactedCustomerDetailVO : orDefault) {
                        List<BigDecimal> contracted_amount_list = weekTransactedCustomerDetailVO.getContracted_amount_list();
                        if (CollectionUtils.isNotEmpty(contracted_amount_list)) {
                            for (BigDecimal bigDecimal : contracted_amount_list) {
                                weekCount = weekCount.add(bigDecimal);
                            }
                        }
                    }
                    monthCount = monthCount.add(weekCount);
                    // 完成率
                    if (weekReplayDetailVO.getTarget().compareTo(zero) > 0) {
                        weekReplayDetailVO.setCompletion_rate(weekCount.divide(weekReplayDetailVO.getTarget().multiply(hundred), 2, RoundingMode.HALF_UP));
                    } else {
                        weekReplayDetailVO.setCompletion_rate(zero);
                    }
                    // 查询时间段内需要拜访的客户信息
                    List<BaseWeekCustomerVO> weekCustomerVOList = baseWeekCustomerVOS.stream().filter(customer -> customer.getNext_visit_time() != null).filter(customer -> (customer.getNext_visit_time().isBefore(weekReplayDetailVO.getEnd_date()) || customer.getNext_visit_time().equals(weekReplayDetailVO.getEnd_date())) && (customer.getNext_visit_time().isAfter(weekReplayDetailVO.getBegin_date()) || customer.getNext_visit_time().equals(weekReplayDetailVO.getBegin_date()))).collect(Collectors.toList());
                    // todo 加入历史拜访数据
                    List<CustomerFollow> collect = follows.stream().filter(item -> (item.getFollow_time().isAfter(weekReplayDetailVO.getBegin_date()) || item.getFollow_time().equals(weekReplayDetailVO.getBegin_date())) && item.getFollow_time().isBefore(weekReplayDetailVO.getEnd_date()) || item.getFollow_time().equals(weekReplayDetailVO.getEnd_date())).collect(Collectors.toList());
                    List<BaseWeekCustomerVO> need_join = new ArrayList<>();
                    // 找出此周期内需要拜访的客户的ids
                    List<Long> customer_ids = weekCustomerVOList.stream().map(BaseWeekCustomerVO::getId).collect(Collectors.toList());
                    // 过滤出此周期内有拜访记录但是再下次拜访客户中搜不到的拜访记录数据
                    List<CustomerFollow> no_has_next_visit_date_list = collect.stream().filter(follow -> !customer_ids.contains(follow.getCustomer_id())).collect(Collectors.toList());
                    no_has_next_visit_date_list.forEach(record -> {
                        if (customer_map.containsKey(record.getCustomer_id())) {
                            BaseWeekCustomerVO t = new BaseWeekCustomerVO();
                            t.setId(record.getCustomer_id());
                            t.setName(customer_map.get(record.getCustomer_id()).getName());
                            t.setNext_visit_time(record.getFollow_time());
                            t.setVisited(true);
                            need_join.add(t);
                        }
                    });
                    // 过滤出此周期内有拜访记录并且也有下次拜访客户的拜访记录数据
                    List<CustomerFollow> has_next_visit_date_list = collect.stream().filter(follow -> customer_ids.contains(follow.getCustomer_id())).collect(Collectors.toList());
                    // 遍历此时间段内需要拜访的客户
                    // 找出是否有和下次拜访时间同一天并且是同一个客户的拜访记录 有则修改拜访状态
                    weekCustomerVOList.forEach(item -> {
                        List<CustomerFollow> followList = has_next_visit_date_list.stream().filter(record -> record.getCustomer_id().equals(item.getId())).collect(Collectors.toList());
                        // 此周期内此客户有拜访并且和下次拜访时间重叠的
                        List<CustomerFollow> collect1 = followList.stream().filter(record -> record.getFollow_time().equals(item.getNext_visit_time())).collect(Collectors.toList());
                        // 此周期内此客户有拜访但是没有下次拜访时间重叠的
                        List<CustomerFollow> collect2 = followList.stream().filter(record -> !record.getFollow_time().equals(item.getNext_visit_time())).collect(Collectors.toList());
                        if (collect1.size() > 0) {
                            item.setVisited(true);
                        } else {
                            item.setVisited(false);
                        }
                        collect2.forEach(record -> {
                            if (customer_map.containsKey(record.getCustomer_id())) {
                                BaseWeekCustomerVO t = new BaseWeekCustomerVO();
                                t.setId(record.getCustomer_id());
                                t.setName(customer_map.get(record.getCustomer_id()).getName());
                                t.setNext_visit_time(record.getFollow_time());
                                t.setVisited(true);
                                need_join.add(t);
                            }
                        });
                    });
                    // 加入拜访记录数据 再进行排序
                    weekCustomerVOList.addAll(need_join);
                    weekCustomerVOList = weekCustomerVOList.stream().sorted(Comparator.comparing(BaseWeekCustomerVO::getNext_visit_time).thenComparing(BaseWeekCustomerVO::getId)).collect(Collectors.toList());
                    weekReplayDetailVO.setNeed_visit_customer_list(weekCustomerVOList);
                    weekReplayDetailList.add(weekReplayDetailVO);
                }
            }
            vo.setTarget(count);
            // 设置周复盘详情
            vo.setWeekReplayDetailList(weekReplayDetailList);
            // 设置月度完成率
            if (vo.getTarget().compareTo(zero) > 0) {
                vo.setCompletion_rate(monthCount.divide(vo.getTarget().multiply(hundred), 2, RoundingMode.HALF_UP));
            } else {
                vo.setCompletion_rate(zero);
            }
            // 设置月度完成金额
            vo.setAmount_completed(monthCount);
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrEditSigningTime(SigningTimeDTO dto) {
        Long user_id = ThreadLocalUserUtil.get().getId();
        YearWeek week = yearWeekService.getById(dto.getWeek_id());
        if (week == null) {
            throw new CommonException("周数据不存在");
        }
        if (dto.getRecord_id() == null && dto.getTarget_record_id() == null) {
            // 获取客户的维护人id赋值user_id
            CustomerInfo customerInfo = customerInfoService.getOne(Wrappers.<CustomerInfo>lambdaQuery().select(CustomerInfo::getId, CustomerInfo::getMaintenance_staff_id).eq(CustomerInfo::getId, dto.getId()));
            if (customerInfo != null) user_id = customerInfo.getMaintenance_staff_id();
            //保存客户每周的客户目标表
            SaleWeekCustomerTarget target = new SaleWeekCustomerTarget();
            target.setCustomer_id(dto.getId());
            target.setWeek_id(dto.getWeek_id());
            target.setUser_id(user_id);
            target.setTarget_quota(dto.getQuota().divide(ten_thousand, 6, RoundingMode.HALF_UP));
            target.setIs_created(false);
            // 添加客户预估签单记录
            CustomerEstimateRecord record = new CustomerEstimateRecord();
            record.setCustomer_id(dto.getId());
            record.setWeek_id(dto.getWeek_id());
            record.setQuota(dto.getQuota());
            record.setTransaction_evaluation(dto.getTransaction_evaluation());
            return saleWeekCustomerTargetService.save(target) && customerEstimateRecordService.save(record);
        } else {
            //修改客户每周的客户目标表
            SaleWeekCustomerTarget target = saleWeekCustomerTargetService.getById(dto.getTarget_record_id());
            if (target == null) {
                throw new CommonException("数据异常,请联系管理员");
            }
            target.setCustomer_id(dto.getId());
            target.setWeek_id(dto.getWeek_id());
//            target.setUser_id(user_id);
            target.setTarget_quota(dto.getQuota().divide(ten_thousand, 6, RoundingMode.HALF_UP));
            target.setIs_created(false);
            // 添加客户预估签单记录
            CustomerEstimateRecord record = customerEstimateRecordService.getById(dto.getRecord_id());
            if (record == null) {
                throw new CommonException("数据异常,请联系管理员");
            }
            record.setCustomer_id(dto.getId());
            record.setWeek_id(dto.getWeek_id());
            record.setQuota(dto.getQuota());
            record.setTransaction_evaluation(dto.getTransaction_evaluation());
            return saleWeekCustomerTargetService.updateById(target) && customerEstimateRecordService.updateById(record);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addVisitRecord(VisitRecordDTO dto) {
        CustomerFollow follow = new CustomerFollow();
        follow.setCustomer_id(dto.getId());
        follow.setFollow_time(dto.getFollow_time());
        follow.setAchievements(dto.getAchievements());
        follow.setPhone(dto.getPhone());
        follow.setOpposite_person(dto.getOpposite_person());
        follow.setReasons_for_recommendation(dto.getReasons_for_recommendation());
        customerFollowService.save(follow);
        customerFollowAdvanceService.saveBatch(dto.getAction_list().stream().map(item -> {
            CustomerFollowAdvance advance = new CustomerFollowAdvance();
            advance.setCustomer_follow_id(follow.getId());
            advance.setAdvance_id(item);
            return advance;
        }).collect(Collectors.toList()));
        customerRecommendedResourcesService.saveBatch(dto.getResource_list().stream().map(item -> {
            CustomerRecommendedResources resources = new CustomerRecommendedResources();
            resources.setCustomer_follow_id(follow.getId());
            resources.setResources_id(item);
            return resources;
        }).collect(Collectors.toList()));
        if(CollectionUtils.isNotEmpty(dto.getUrl_list()))
            customerFollowPhotoService.saveBatch(dto.getUrl_list().stream().map(url -> {
                CustomerFollowPhoto photo = new CustomerFollowPhoto();
                photo.setUrl(url);
                photo.setFollow_id(follow.getId());
                return photo;
            }).collect(Collectors.toList()));
        return true;
    }

    @Override
    public Page<SignatureHistoryVO> signatureHistoryList(Integer current_page, Integer page_size, Long customer_id, LocalDate begin_date, LocalDate end_date) {
        Page<SignatureHistoryVO> page = new Page<>(current_page, page_size);
        List<SignatureHistoryVO> signatureHistoryDataList = saleWeekCustomerTargetService.querySignatureHistoryList(page, customer_id, begin_date, end_date);
        List<Long> ids = new ArrayList<>();
        ids.add(customer_id);
        LocalDate now = LocalDate.now();
        List<ContractApply> contractApplies = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, ids);
        for (SignatureHistoryVO signatureHistoryData : signatureHistoryDataList) {
            BigDecimal pay_cash_amount_count = new BigDecimal(0);
            BigDecimal displace_amount_count = new BigDecimal(0);
            List<ContractApply> contractApplyList = contractApplies.stream().filter(contract -> (contract.getSign_date().isBefore(signatureHistoryData.getEnd_date()) || contract.getSign_date().equals(signatureHistoryData.getEnd_date())) && (contract.getSign_date().isAfter(signatureHistoryData.getBegin_date()) || contract.getSign_date().equals(signatureHistoryData.getBegin_date()))).collect(Collectors.toList());
            for (ContractApply contractApply : contractApplyList) {
                pay_cash_amount_count = pay_cash_amount_count.add(contractApply.getPay_cash_amount());
                displace_amount_count = displace_amount_count.add(contractApply.getDisplace_amount());
            }
            signatureHistoryData.setTransaction_evaluation(signatureHistoryData.getTransaction_evaluation().multiply(hundred));
            signatureHistoryData.setDisplace_amount_count(displace_amount_count);
            signatureHistoryData.setPay_cash_amount_count(pay_cash_amount_count);
            BigDecimal count = new BigDecimal(0);
            count = count.add(displace_amount_count).add(pay_cash_amount_count);
            // 如果成交
            if (count.compareTo(signatureHistoryData.getQuota()) >= 0) {
                signatureHistoryData.setInvalid(1);
            } else if (count.compareTo(signatureHistoryData.getQuota()) < 0 && (signatureHistoryData.getEnd_date().isAfter(now) || signatureHistoryData.getEnd_date().equals(now))) {
                // 未成交但是没到结束日期
                signatureHistoryData.setInvalid(2);
            } else {
                // 时间过了未成交
                signatureHistoryData.setInvalid(3);
            }
        }
        page.setRecords(signatureHistoryDataList);
        return page;
    }

    @Override
    public NextMonthTargetVO nextMonthTarget(Integer type) {
        NextMonthTargetVO vo = new NextMonthTargetVO();
        // 获取当前时间
        LocalDate date = LocalDate.now();
        // 加一个月
        if (date.getMonthValue() == 12) {
            date = LocalDate.of(date.getYear() + 1, 1, 1);
        } else {
            date = LocalDate.of(date.getYear(), date.getMonthValue() + 1, 1);
        }
        Year year = yearService.getOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, date.getYear()).eq(Year::getType, date.getMonthValue() <= 6 ? 1 : 2));
        vo.setMonth(date.getMonthValue());
        if (year == null) {
            return vo;
        }
        // 获取当前人的id
        Long user_id = ThreadLocalUserUtil.get().getId();
        BigDecimal target = new BigDecimal(0);
        List<YearWeek> list = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, year.getId()).eq(YearWeek::getMonth, date.getMonthValue()));
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> week_ids = list.stream().map(YearWeek::getId).collect(Collectors.toList());
            Map<Long, List<SaleWeekTarget>> sale_week_target_map = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().eq(SaleWeekTarget::getUser_id, user_id).in(SaleWeekTarget::getWeek_id, week_ids).eq(SaleWeekTarget::getType, type)).stream().collect(Collectors.groupingBy(SaleWeekTarget::getWeek_id));
            Map<Long, List<SaleWeekCustomerTargetVO>> sale_week_customer_target_map = saleWeekCustomerTargetService.querySaleWeekCustomerTargetVOList(type, week_ids, user_id).stream().collect(Collectors.groupingBy(SaleWeekCustomerTarget::getWeek_id));
            List<NextMonthWeekCustomerVO> weekCustomerVOList = new ArrayList<>();
            for (YearWeek item : list) {
                NextMonthWeekCustomerVO weekCustomerVO = new NextMonthWeekCustomerVO();
                weekCustomerVO.setWeek_id(item.getId());
                weekCustomerVO.setBegin_date(item.getBegin_date());
                weekCustomerVO.setEnd_date(item.getEnd_date());
                weekCustomerVO.setMonth(item.getMonth());
                if (sale_week_target_map != null && sale_week_target_map.size() > 0 && sale_week_target_map.containsKey(item.getId())) {
                    SaleWeekTarget saleWeekTarget = sale_week_target_map.get(item.getId()).get(0);
                    weekCustomerVO.setTarget(saleWeekTarget.getTarget_quota());
                    target = target.add(saleWeekTarget.getTarget_quota());
                } else {
                    weekCustomerVO.setTarget(new BigDecimal(0));
                }
                weekCustomerVO.setCustomerTargetVOList(sale_week_customer_target_map.getOrDefault(item.getId(), new ArrayList<>()));
                weekCustomerVOList.add(weekCustomerVO);
            }
            vo.setWeekCustomerVOList(weekCustomerVOList);
        } else {
            vo.setWeekCustomerVOList(new ArrayList<>());
        }
        vo.setTarget(target);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveThisMonthCustomerTarget(List<FillWeekCustomerTargetDTO> dtoList) {
        if (CollectionUtils.isNotEmpty(dtoList)) {
            Map<Long, List<FillWeekCustomerTargetDTO>> dataMap = dtoList.stream().collect(Collectors.groupingBy(FillWeekCustomerTargetDTO::getSale_week_customer_target_id));
            List<SaleWeekCustomerTarget> list = saleWeekCustomerTargetService.list(Wrappers.<SaleWeekCustomerTarget>lambdaQuery().in(SaleWeekCustomerTarget::getId, dtoList.stream().map(FillWeekCustomerTargetDTO::getSale_week_customer_target_id).collect(Collectors.toList())));
            List<CustomerEstimateRecord> recordList = new ArrayList<>();
            list.forEach(item -> {
                CustomerEstimateRecord record = new CustomerEstimateRecord();
                if (dataMap.containsKey(item.getId())) {
                    record.setQuota(dataMap.get(item.getId()).get(0).getTarget().multiply(ten_thousand));
                } else {
                    record.setQuota(item.getTarget_quota().multiply(ten_thousand));
                }
                record.setCustomer_id(item.getCustomer_id());
                record.setWeek_id(item.getWeek_id());
                recordList.add(record);
            });
            List<SaleWeekCustomerTarget> collect = dtoList.stream().map(item -> {
                SaleWeekCustomerTarget target = new SaleWeekCustomerTarget();
                target.setId(item.getSale_week_customer_target_id());
                target.setIs_created(false);
                target.setTarget_quota(item.getTarget());
                return target;
            }).collect(Collectors.toList());
            recordList.forEach(record -> {
                customerEstimateRecordService.update(Wrappers.<CustomerEstimateRecord>lambdaUpdate().
                        set(CustomerEstimateRecord::getQuota, record.getQuota()).
                        eq(CustomerEstimateRecord::getCustomer_id, record.getCustomer_id())
                        .eq(CustomerEstimateRecord::getWeek_id, record.getWeek_id())
                        .isNull(CustomerEstimateRecord::getDeleted_at));
            });
            return saleWeekCustomerTargetService.updateBatchById(collect);
        } else {
            return true;
        }
    }

    @Override
    public Boolean confirmReceive(Long id) {
        return customerVisitCommentsService.update(Wrappers.<CustomerVisitComments>lambdaUpdate().set(CustomerVisitComments::getReceived_or_not, true).eq(CustomerVisitComments::getId, id));
    }
}
